import { Injectable } from '@nestjs/common';
import { fork, ChildProcess } from 'node:child_process';
import * as path from 'path';

@Injectable()
export class ChildProcessService {
  private childProcesses: ChildProcess[] = [];

  /**
   * 创建并执行子进程任务
   * @param data 要处理的数据
   * @returns Promise<any> 子进程执行结果
   */
  async createChildProcessTask(data: any): Promise<any> {
    return new Promise((resolve, reject) => {
      // 编译后的服务文件在dist/child-process/child.js下
      let childPath = path.join(__dirname, '../../child-process/files/child.js');

      // 创建子进程，使用完整的stdio配置以支持所有必要的通信通道
      // 使用['pipe', 'pipe', 'pipe', 'ipc']可以确保stdin、stdout、stderr和IPC通道都正常工作
      const childProcess = fork(childPath, [], {
        stdio: ['pipe', 'pipe', 'pipe', 'ipc'],
      });
      console.log('子进程PID:', childProcess.pid);

      // 捕获子进程的stdout输出，用于调试
      childProcess.stdout?.on('data', (data) => {
        console.log('子进程stdout:', data.toString());
      });

      // 捕获子进程的stderr输出，用于调试
      childProcess.stderr?.on('data', (data) => {
        console.error('子进程stderr:', data.toString());
      });

      // 存储子进程引用以便后续管理
      this.childProcesses.push(childProcess);

      // 限制子进程数量，避免资源耗尽
      this.cleanupIdleProcesses();

      // 监听子进程消息
      childProcess.on('message', (result) => {
        console.log('子进程执行结果:', result);
        resolve(result);
      });

      // 监听错误事件
      childProcess.on('error', (err) => {
        console.error('子进程错误:', err);
        reject(err);
      });

      // 监听退出事件
      childProcess.on('exit', (code, signal) => {
        console.log(
          `子进程 ${childProcess.pid} 退出，退出码: ${code}，信号: ${signal}`,
        );

        // 从数组中移除已退出的子进程
        this.childProcesses = this.childProcesses.filter(
          (p) => p.pid !== childProcess.pid,
        );

        if (code !== 0 && !signal) {
          reject(new Error(`子进程意外退出，退出码: ${code}`));
        }
      });

      // 向子进程发送数据
      childProcess.send(data);

      // 设置超时，防止子进程无限阻塞
      setTimeout(() => {
        if (this.childProcesses.includes(childProcess)) {
          childProcess.kill(); // 主进程主动kill子进程，避免资源泄漏
          reject(new Error('子进程执行超时'));
        }
      }, 30000);
    });
  }

  /**
   * 清理空闲的子进程，防止资源泄漏
   */
  private cleanupIdleProcesses(): void {
    const maxProcesses = 5; // 最大子进程数量限制
    if (this.childProcesses.length > maxProcesses) {
      const processesToKill = this.childProcesses.length - maxProcesses;

      // 终止最早创建的子进程
      for (let i = 0; i < processesToKill; i++) {
        const processToKill = this.childProcesses[i];
        try {
          processToKill.kill();
        } catch (err) {
          console.error('终止子进程失败:', err);
        }
      }
      // 更新子进程列表
      this.childProcesses = this.childProcesses.slice(processesToKill);
    }
  }

  /**
   * 获取当前活跃子进程数量
   */
  getActiveProcessCount(): number {
    return this.childProcesses.length;
  }
}
